/*******************************************************************************
Copyright (c) 2021-2022 Qualcomm Technologies International, Ltd.
 %%version
*******************************************************************************/

#include "gatt_cas_server.h"
#include "gatt_cas_server_private.h"
#include "gatt_cas_server_msg_handler.h"
#include "gatt_cas_server_access.h"
#include "gatt_cas_server_common.h"
#include "gatt_cas_server_db.h"
#include "gatt_cas_server_debug.h"

/******************************************************************************/
ServiceHandle cas_service_handle;

/******************************************************************************/
ServiceHandle GattCasServerInit(
                     AppTask    theAppTask,
                     uint16  startHandle,
                     uint16  endHandle,
                     GattCasInitData initData)
{
    UNUSED(initData);
    GCAS *gatt_cas_server_inst = NULL;

    if (theAppTask == CSR_SCHED_QID_INVALID)
    {
        GATT_CAS_SERVER_PANIC("Application Task NULL\n");
    }

    cas_service_handle = ServiceHandleNewInstance((void **) &gatt_cas_server_inst, sizeof(GCAS));

    if (gatt_cas_server_inst)
    {
        /* Reset all the service library memory */
        CsrMemSet(gatt_cas_server_inst, 0, sizeof(GCAS));

        /* Store the Task function parameter.
         * All library messages need to be sent here */
        gatt_cas_server_inst->app_task = theAppTask;

        /* Save the service handle */
        gatt_cas_server_inst->srvcHndl = cas_service_handle;
        gatt_cas_server_inst->startHandle = startHandle;
        gatt_cas_server_inst->endHandle = endHandle;

        /* Initialisation of the Service Characteristics and parameters*/
        /* No characteristics */

        CsrMemSet(gatt_cas_server_inst->data.connected_clients, 0, (sizeof(gatt_cas_client_data) * GATT_CAS_MAX_CONNECTIONS));


        /* Register with GATT */
        CsrBtGattRegisterReqSend(CSR_BT_VCS_SERVER_IFACEQUEUE,
                                 0);

        return cas_service_handle;
    }
    else
    {
        GATT_CAS_SERVER_PANIC("Memory allocation of CAS Server instance failed!\n");
        return 0;
    }
}

/******************************************************************************/
status_t GattCasServerAddConfig(
                  ServiceHandle srvcHndl,
                  connection_id_t cid,
                  const GattCasServerConfig *config)
{
    uint8 i;
    GCAS *common_audio_server = (GCAS *) ServiceHandleGetInstanceData(srvcHndl);

    if (common_audio_server)
    {
        for(i=0; i<GATT_CAS_MAX_CONNECTIONS; i++)
        {
            if(common_audio_server->data.connected_clients[i].cid == 0)
            {
                /* Check config parameter:
                 * If config is NULL, it indicates a default config should be used for the
                 * peer device identified by the CID.
                 * The default config is already set when the instance has been initialised.
                 */
                if (config)
                {           
                    /* Save new ccc for the client */
                    /* no characteristics */
                }

                common_audio_server->data.connected_clients[i].cid = cid;

                return CSR_BT_GATT_RESULT_SUCCESS;
            }
        }
    }

    return CSR_BT_GATT_RESULT_INSUFFICIENT_NUM_OF_HANDLES;
}

/******************************************************************************/
GattCasServerConfig *GattCasServerRemoveConfig(
                              ServiceHandle srvcHndl,
                              connection_id_t  cid)
{
    uint8 i;
    GCAS *common_audio_server = (GCAS *) ServiceHandleGetInstanceData(srvcHndl);
    GattCasServerConfig *config = NULL;

    PanicNull(common_audio_server);

    for(i=0; i<GATT_CAS_MAX_CONNECTIONS; i++)
    {
        /* Check the saved CID to find the peer device */
        if (common_audio_server->data.connected_clients[i].cid == cid)
        {
            /* Found peer device:
             * - save last client configurations
             * - remove the peer device
             * - free the server instance
             * - return last client configuration
             */

            config = PanicUnlessMalloc(sizeof(GattCasServerConfig));
            memcpy(config, &(common_audio_server->data.connected_clients[i].client_cfg), sizeof(GattCasServerConfig));

            if ((i == (GATT_CAS_MAX_CONNECTIONS-1)) || (i == 0 && common_audio_server->data.connected_clients[i+1].cid == 0))
            {
                /* The peer device is the only or the last element of the array */
                memset(&(common_audio_server->data.connected_clients[i]), 0, sizeof(gatt_cas_client_data));
            }
            else
            {
                /* The peer device is in the middle of the array */
                uint8 j;

                for (j=i; j<(GATT_CAS_MAX_CONNECTIONS - 1) && common_audio_server->data.connected_clients[j+1].cid != 0; j++)
                {
                    /* Shift all the elements of the array of one position behind */
                    memmove(&(common_audio_server->data.connected_clients[j]),
                           &(common_audio_server->data.connected_clients[j+1]),
                           sizeof(gatt_cas_client_data));
                }

                /* Remove the last element of the array, already shifted behind */
                memset(&(common_audio_server->data.connected_clients[j]), 0, sizeof(gatt_cas_client_data));
            }
        }
    }

    return config;
}

/******************************************************************************/
/*Synergy Task Init*/

void gatt_cas_server_init(void** gash)
{
    *gash = &cas_service_handle;
    GATT_CAS_SERVER_INFO("CAS: gatt_cas_server_init\n\n");

}

/*Synergy Task deinit*/
#ifdef ENABLE_SHUTDOWN
void gatt_cas_server_deinit(void** gash)
{
    ServiceHandle srvcHndl = *((ServiceHandle*)*gash);
    if(ServiceHandleFreeInstanceData(srvcHndl))
    {
        GATT_CAS_SERVER_INFO("GCAS: gatt_cas_client_deinit\n\n");
    }
    else
    {
        GATT_CAS_SERVER_PANIC("Unable to free the CAS server instance\n");
    }
}
#endif


